// FilterModule.tsx
import React, {
  useCallback,
  useState,
  useRef,
  useLayoutEffect,
  useMemo,
  useEffect,
} from "react";
import { useTranslation } from "react-i18next";
import { FilterModuleProps } from "./type";
import ButtonAtom from "../../Atoms/Button.Atom";
import ButtonAtomEnum from "../../Atoms/Button.Atom/enum";
import ImageAtom from "../../Atoms/Image.Atom";
import ImageEnum from "../../Atoms/Image.Atom/enum";
import CloseIcon from "../../../shared/icons/close.svg?react";
import FilterModuleEnum from "./enum";
import SearchModuleMolecule from "../../Molecules/SearchModule.molecule";
import FiltersItemsMolecule from "../../Molecules/FiltersItems.molecule";
import PriceFilterModuleCeil from "../../Cells/PriceFilterModule.ceil";
import TextAtom from "../../Atoms/Text.Atom";
import TextAtomEnum from "../../Atoms/Text.Atom/enum";

const FilterModule: React.FC<FilterModuleProps> = (props) => {
  const { t } = useTranslation();
  const {
    type,
    itemTitle,
    items,
    lengths,
    applyFilters,
    filters,
    filterKey,
    maxPrice,
  } = props;

  const [priceRange, setPriceRange] = useState<[number, number]>([
    filters.price?.[0] || 0,
    filters.price?.[1] || maxPrice,
  ]);

  useEffect(() => {
    setPriceRange([filters.price?.[0] || 0, filters.price?.[1] || maxPrice]);
  }, [filters.price, maxPrice]);

  const initialSelectedFilters = useMemo(() => {
    const selectedItems = filters[filterKey] || [];
    return items?.map((item: [string]) => selectedItems.includes(item));
  }, [filters, filterKey, items]);

  const [selectedFilters, setSelectedFilters] = useState<boolean[]>(
    initialSelectedFilters
  );
  const [searchQuery, setSearchQuery] = useState("");
  const [isMenuOpen, setIsMenuOpen] = useState(false);
  const menuRef = useRef<HTMLDivElement>(null);

  const handleApplyFilters = useCallback(() => {
    if (type === FilterModuleEnum.enum_priceModuleFilter) {
      const priceFilter = {
        price: [Math.round(priceRange[0]), Math.round(priceRange[1])],
      };
      applyFilters({ ...filters, ...priceFilter });
    } else {
      const selectedItems = selectedFilters
        .map((filter, index) => (filter ? items[index] : null))
        .filter(Boolean);
      applyFilters({ ...filters, [filterKey]: selectedItems });
    }
    setIsMenuOpen(false);
  }, [
    type,
    applyFilters,
    filters,
    priceRange,
    selectedFilters,
    items,
    filterKey,
  ]);

  const selectedFilterCount = useMemo(
    () => selectedFilters?.filter((filter) => filter).length,
    [selectedFilters]
  );

  const toggleMenu = useCallback(() => {
    setIsMenuOpen((prevIsMenuOpen) => !prevIsMenuOpen);
  }, []);

  const clearSelectedFilters = useCallback(() => {
    applyFilters({ ...filters, [filterKey]: [] });
    setIsMenuOpen(false);
  }, [applyFilters, filters, filterKey]);

  const handleClickOutside = useCallback((event: MouseEvent) => {
    if (menuRef.current && !menuRef.current.contains(event.target as Node)) {
      setIsMenuOpen(false);
    }
  }, []);

  useLayoutEffect(() => {
    document.addEventListener("mousedown", handleClickOutside);
    return () => {
      document.removeEventListener("mousedown", handleClickOutside);
    };
  }, [handleClickOutside]);

  useEffect(() => {
    setSelectedFilters(initialSelectedFilters);
  }, [initialSelectedFilters]);

  const handlePriceChange = useCallback((newPriceRange: [number, number]) => {
    setPriceRange(newPriceRange);
  }, []);

  return (
    <div ref={menuRef} className="relative inline-block">
      <div
        onClick={toggleMenu}
        className={`flex cursor-pointer rounded items-stretch gap-2 py-2 px-3  ${
          filters[filterKey]?.length > 0
            ? "border-[1px] border-transparent border-solid bg-bg_hover text-white fill-white"
            : "border-[1px] border-gray border-solid hover:border-bg_hover text-textColor"
        }`}
      >
        <TextAtom
          type={TextAtomEnum.enum_h4}
          className="tracking-wide font-medium"
        >
          {itemTitle}
        </TextAtom>
        {filters[filterKey]?.length > 0 && (
          <div className="flex items-center gap-1">
            <TextAtom
              type={TextAtomEnum.enum_h5}
              className="font-medium uppercase"
            >
              ({selectedFilterCount})
            </TextAtom>
            <ImageAtom
              onClick={clearSelectedFilters}
              type={ImageEnum.enum_defaultSvg}
              icon={<CloseIcon />}
              className="w-3 h-3 cursor-pointer hover:fill-peach"
            />
          </div>
        )}
      </div>
      {isMenuOpen && (
        <div className="absolute top-[40px] left-0 w-72 bg-bgGen rounded-lg border-[2px] border-borderColor shadow-sm py-[10px] z-20">
          {type === FilterModuleEnum.enum_otherModuleFilter && (
            <React.Fragment>
              <div className="mx-4 mb-3">
                <SearchModuleMolecule
                  value={searchQuery}
                  setSearchQuery={setSearchQuery}
                />
              </div>
              <FiltersItemsMolecule
                items={items}
                searchQuery={searchQuery}
                setSelectedFilters={setSelectedFilters}
                selectedFilters={selectedFilters}
                lengths={lengths}
              />
            </React.Fragment>
          )}
          {type === FilterModuleEnum.enum_priceModuleFilter && (
            <div className="flex-col pt-[40px] pb-[10px] px-[16px]">
              <PriceFilterModuleCeil
                maxPrice={maxPrice}
                priceRange={priceRange}
                handlePriceChange={handlePriceChange}
              />
            </div>
          )}
          <div className="pt-[10px] px-[16px]">
            <ButtonAtom
              type={ButtonAtomEnum.enum_butButton}
              onClick={handleApplyFilters}
            >
              {t("filterOrganism.submitButton")}
            </ButtonAtom>
          </div>
        </div>
      )}
    </div>
  );
};

export default React.memo(FilterModule);
